#!/bin/bash
APP_CONTENTS="$(cd "$(dirname "$0")/.." && pwd)"
SRC="$APP_CONTENTS/Resources/SPMCOrganizerMac.swift"
ORGANIZER_ROOT="$APP_CONTENTS/Resources/Organizer"
NATIVE_ROOT="$HOME/Library/Application Support/SPMC Organizer/Native"
CACHE="$NATIVE_ROOT/runtime-v2"
BIN="$CACHE/SPMCOrganizer"
HASH_FILE="$CACHE/source.sha256"
LOG="$HOME/Library/Logs/SPMC Organizer.log"
COMPILE_LOG="$CACHE/compile.log"
LOCK="$CACHE/.compile.lock"

mkdir -p "$CACHE" "$(dirname "$LOG")"

BOOT_START=$(/bin/date +%s)
log_boot() {
  local now elapsed
  now=$(/bin/date +%s)
  elapsed=$((now-BOOT_START))
  printf '[%s] BOOT191 +%ss %s\n' "$(/bin/date '+%Y-%m-%d %H:%M:%S')" "$elapsed" "$1" >>"$LOG"
}

log_boot "launcher iniciado"

# Remove somente um servidor local antigo do proprio Organizer que tenha ficado preso na porta 8790.
if command -v /usr/sbin/lsof >/dev/null 2>&1; then
  for PID in $(/usr/sbin/lsof -tiTCP:8790 -sTCP:LISTEN 2>/dev/null); do
    CMD=$(/bin/ps -p "$PID" -o command= 2>/dev/null || true)
    if [[ "$CMD" == *"http.server 8790"* ]] && [[ "$CMD" == *"127.0.0.1"* ]]; then
      /bin/kill "$PID" 2>/dev/null || true
    fi
  done
fi

if [ ! -f "$ORGANIZER_ROOT/index.html" ]; then
  /usr/bin/osascript -e 'display dialog "SPMC Organizer não encontrou index.html dentro do aplicativo." buttons {"OK"} default button "OK" with icon stop'
  exit 1
fi

if [ ! -f "$SRC" ]; then
  /usr/bin/osascript -e 'display dialog "SPMC Organizer não encontrou o componente nativo Swift dentro do aplicativo." buttons {"OK"} default button "OK" with icon stop'
  exit 1
fi

SRC_HASH=$(/usr/bin/shasum -a 256 "$SRC" 2>/dev/null | /usr/bin/awk '{print $1}')
CACHED_HASH=$(/bin/cat "$HASH_FILE" 2>/dev/null || true)

if [ -n "$SRC_HASH" ] && [ -x "$BIN" ] && [ "$SRC_HASH" = "$CACHED_HASH" ]; then
  log_boot "cache nativo SHA válido; compilação ignorada"
else
  log_boot "cache nativo ausente/alterado; compilação necessária"

  if ! /usr/bin/xcrun --find swiftc >/dev/null 2>&1; then
    /usr/bin/osascript -e 'display dialog "SPMC Organizer precisa do compilador Swift do macOS somente quando o componente nativo muda. Instale as Command Line Tools e abra novamente o aplicativo." buttons {"OK"} default button "OK" with icon caution'
    exit 1
  fi

  # Evita duas compilações simultâneas se o usuário clicar duas vezes.
  if /bin/mkdir "$LOCK" 2>/dev/null; then
    TMP_BIN="$CACHE/SPMCOrganizer.tmp.$$"
    : >"$COMPILE_LOG"
    if /usr/bin/xcrun swiftc "$SRC" -o "$TMP_BIN" -framework Cocoa -framework WebKit -framework Network -framework AuthenticationServices -framework AVFoundation -framework PDFKit >"$COMPILE_LOG" 2>&1; then
      /bin/chmod 755 "$TMP_BIN"
      /bin/mv -f "$TMP_BIN" "$BIN"
      printf '%s\n' "$SRC_HASH" >"$HASH_FILE.tmp"
      /bin/mv -f "$HASH_FILE.tmp" "$HASH_FILE"
      log_boot "compilação concluída e SHA salvo"
    else
      /bin/rm -f "$TMP_BIN" "$HASH_FILE.tmp" 2>/dev/null || true
      /bin/rmdir "$LOCK" 2>/dev/null || true
      /bin/cat "$COMPILE_LOG" >>"$LOG" 2>/dev/null || true
      /usr/bin/osascript -e 'display dialog "Falha ao preparar o componente WKWebView. Consulte ~/Library/Logs/SPMC Organizer.log" buttons {"OK"} default button "OK" with icon stop'
      exit 1
    fi
    /bin/rmdir "$LOCK" 2>/dev/null || true
  else
    # Outra instância está compilando. Aguarda o cache aparecer, sem disparar outro swiftc.
    for _ in $(/usr/bin/seq 1 90); do
      CACHED_HASH=$(/bin/cat "$HASH_FILE" 2>/dev/null || true)
      if [ -x "$BIN" ] && [ -n "$SRC_HASH" ] && [ "$SRC_HASH" = "$CACHED_HASH" ]; then
        log_boot "cache concluído por outra instância"
        break
      fi
      /bin/sleep 1
    done
    CACHED_HASH=$(/bin/cat "$HASH_FILE" 2>/dev/null || true)
    if [ ! -x "$BIN" ] || [ -z "$SRC_HASH" ] || [ "$SRC_HASH" != "$CACHED_HASH" ]; then
      log_boot "timeout aguardando compilação concorrente"
      exit 1
    fi
  fi
fi

export SPMC_ORGANIZER_ROOT="$ORGANIZER_ROOT"
export SPMC_BOOT191_START="$BOOT_START"
log_boot "executando binário nativo"
exec "$BIN"
